home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / ada / gnat-3.05- / gnat-3 / gnat-3.05-i486-linux-elf-bin / rts / a-init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-07  |  7.3 KB  |  196 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                         GNAT COMPILER COMPONENTS                         */
  4. /*                                                                          */
  5. /*                               A - I N I T                                */
  6. /*                                                                          */
  7. /*                            $Revision: 1.6 $                              */
  8. /*                                                                          */
  9. /*                          C Implementation File                           */
  10. /*                                                                          */
  11. /*    Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.   */
  12. /*                                                                          */
  13. /* GNAT is free software;  you can  redistribute it  and/or modify it under */
  14. /* terms of the  GNU General Public License as published  by the Free Soft- */
  15. /* ware  Foundation;  either version 2,  or (at your option) any later ver- */
  16. /* sion.  GNAT is distributed in the hope that it will be useful, but WITH- */
  17. /* OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY */
  18. /* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License */
  19. /* for  more details.  You should have  received  a copy of the GNU General */
  20. /* Public License  distributed with GNAT;  see file COPYING.  If not, write */
  21. /* to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, */
  22. /* MA 02111-1307, USA.                                                      */
  23. /*                                                                          */
  24. /* As a  special  exception,  if you  link  this file  with other  files to */
  25. /* produce an executable,  this file does not by itself cause the resulting */
  26. /* executable to be covered by the GNU General Public License. This except- */
  27. /* ion does not  however invalidate  any other reasons  why the  executable */
  28. /* file might be covered by the  GNU Public License.                        */
  29. /*                                                                          */
  30. /* GNAT was originally developed  by the GNAT team at  New York University. */
  31. /* It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). */
  32. /*                                                                          */
  33. /****************************************************************************/
  34.  
  35. /* This routine is called right at the start of execution of an Ada program
  36.    (the call is generated by the binder). The standard routine does nothing
  37.    at all, the intention is that this be replaced by system specific code
  38.    where initialization is required. */
  39.  
  40. #if (!defined (MSDOS) && !defined (sgi))
  41. /* This routine is called right at the start of execution of an Ada program
  42.    (the call is generated by the binder). The standard routine does nothing
  43.    at all, the intention is that this be replaced by system specific code
  44.    where initialization is required. */
  45.  
  46. __gnat_initialize()
  47. {
  48. }
  49. #endif
  50.  
  51. #if defined (MSDOS)
  52. #include <stdio.h>
  53.  
  54. /* This is DOS specific.  It does nothing unless run from an 
  55.    environment that creates a gw-gnat.$$$ file.  If that file is present,
  56.    it forces all program output to the console.  This allows the debugger
  57.    to be run sending output to a file, but the program output still goes
  58.    to the console. */
  59.  
  60. __gnat_initialize()
  61. {
  62.     if (access("gw-gnat.$$$", 0) == 0)
  63.     freopen("CON", "w", stdout);
  64. }
  65. #endif
  66.  
  67. #if defined (sgi)
  68. /* This is SGI specific */
  69.  
  70. #include <signal.h>
  71. #include <sys/siginfo.h>
  72. #include <sys/ucontext.h>
  73. #include <sys/types.h>
  74.  
  75. /* #include "a-raise.h" */
  76.  
  77. #define SIGNAL_STACK_SIZE 4096
  78. #define SIGNAL_STACK_ALIGNMENT 64
  79. #define NULL 0
  80.  
  81. extern char constraint_error asm ("constraint_error");
  82. extern char numeric_error    asm ("numeric_error");
  83. extern char program_error    asm ("program_error");
  84. extern char storage_error    asm ("storage_error");
  85. extern char tasking_error    asm ("tasking_error");
  86. extern char _abort_signal    asm ("_abort_signal");
  87.  
  88. extern void  system__task_specific_data__set_gnat_exception (void* e);
  89. extern char *system__task_specific_data__get_gnat_exception ();
  90. extern int  *system__task_specific_data__get_jmpbuf_address ();
  91. extern void *system__task_specific_data__get_exc_stack_addr ();
  92. extern void  __gnat_reraise ();
  93.  
  94. char* signal_stack;                       /* Alternate signal stack */
  95.  
  96. static void __gnat_error_handler (int sig, int code, struct sigcontext *sc)
  97. {
  98.  
  99.   char* exception;
  100.   void* exc_stack = system__task_specific_data__get_exc_stack_addr ();
  101.  
  102.   if (sig == SIGSEGV) {
  103.  
  104.     if (code == SEGV_MAPERR) {
  105.       /* Assume reference to unmapped pages is a bad pointer dereference
  106.          and map it to constraint_error */
  107.       exception = &constraint_error;
  108.  
  109.     } else {
  110.       /* Otherwise we: are referencing a mapped page that is protected, or
  111.          have reached our process's stack limit (see setrlimit(2)).
  112.          In both cases, raise Storage_Error */
  113.       exception = &storage_error;
  114.     }
  115.  
  116.   } else if (sig == SIGBUS) {
  117.     /* Map all bus errors to constraint_error */
  118.     exception = &constraint_error;
  119.  
  120.   } else if (sig == SIGFPE) {
  121.     /* Map all fpe errors to constraint_error */
  122.     exception = &constraint_error;
  123.  
  124.   } else {
  125.     /* Everything else is a program_error */
  126.     exception = &program_error;
  127.   }
  128.  
  129.   system__task_specific_data__set_gnat_exception (exception);
  130.  
  131.   /*  Overwrite the signal context's saved PC with the address of
  132.       the gnat_reraise routine, so the return from this handler
  133.       will resume execution at the raise point. */
  134.  
  135. /*  sc->sc_pc = (__uint64_t) ((int)__gnat_reraise + 0xC); */
  136.   sc->sc_pc = (__uint64_t) ((int)__gnat_reraise);
  137.  
  138.   /*  Overwrite the saved SP value with the thread's special exception
  139.       stack pointer so the exception propagation code will run on
  140.       that stack.  This is necessary if we are raising Storage_Error
  141.       resulting from a task stack overrun. */
  142.  
  143.   sc->sc_regs [CTX_SP] = (__uint64_t) ((int)exc_stack);
  144.  
  145.   /* Set T9 to the address of __gnat_reraise so the GP adjustment in
  146.      the function prologue is correct */
  147.  
  148.   sc->sc_regs [CTX_T9] = (__uint64_t) ((int)__gnat_reraise);
  149.  
  150.   /* Set the first argument register (a0/$4) to -1 so that gnat_reraise
  151.      will call abort_defer prior to propagating the exception. */
  152.  
  153.   sc->sc_regs [CTX_A0] = -1;
  154.  
  155. }
  156.  
  157.  
  158.  
  159. static __gnat_install_handler ()
  160. {
  161.  
  162.   stack_t ss;
  163.   struct sigaction act;
  164.  
  165.   /* Setup alternate signal stack */
  166.  
  167.   signal_stack = (char*) memalign (SIGNAL_STACK_ALIGNMENT, SIGNAL_STACK_SIZE);
  168.  
  169.   ss.ss_sp    = &signal_stack[SIGNAL_STACK_SIZE];
  170.   ss.ss_size  = SIGNAL_STACK_SIZE;
  171.   ss.ss_flags = 0;
  172.  
  173.   (void) sigaltstack (&ss, NULL);
  174.  
  175.   /* Setup signal handler to map synchronous signals to appropriate
  176.      exceptions.  Make sure that the handler isn't interrupted by another
  177.      signal that might cause a scheduling event! */
  178.  
  179.   act.sa_handler = __gnat_error_handler;
  180.   act.sa_flags = SA_ONSTACK + SA_NODEFER;
  181.   (void) sigfillset (&act.sa_mask);
  182.  
  183.   (void) sigaction (SIGILL,  &act, NULL);
  184.   (void) sigaction (SIGABRT, &act, NULL);
  185.   (void) sigaction (SIGFPE,  &act, NULL);
  186.   (void) sigaction (SIGSEGV, &act, NULL);
  187.   (void) sigaction (SIGBUS,  &act, NULL);
  188.  
  189. }
  190. __gnat_initialize()
  191. {
  192.   __gnat_install_handler();
  193. }
  194.  
  195. #endif
  196.